package top.abrsm.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import top.abrsm.config.LogPointer;
import top.abrsm.entity.StudentEntity;
import top.abrsm.service.IStudentService;
import top.abrsm.util.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.net.URLEncoder;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 学生表 前端控制器
 * </p>
 *
 * @author WuZH
 * @since 2023-11-18
 */
@Controller
@RequestMapping ( "/student" )
public class StudentController {

    @Resource
    private IStudentService iStudentService;


    @RequestMapping ( "login" )
    @LogPointer ( "学生端账号密码登录" )
    @ResponseBody
    public ResultBody login ( StudentEntity studentEntity, HttpSession session ) {
        studentEntity = iStudentService.querySingle ( studentEntity );
        if ( studentEntity == null ) {
            return ResultBody.fail ( StateEnum.RESULT_NULL_EXCE );
        }
        studentEntity.setToken ( CommonUtil.getToken () );
        session.setAttribute ( "studentEntity", studentEntity );
        iStudentService.updateSingle ( studentEntity );
        return ResultBody.success ( studentEntity );
    }

    /**
     * 注册学生账号
     *
     * @param studentEntity
     * @return
     */
    @RequestMapping ( "saveSingle" )
    @LogPointer ( "学生端注册考试系统" )
    @ResponseBody
    public ResultBody saveSingle ( StudentEntity studentEntity, HttpSession session ) {
        // 如果过期了或者号码不对，则在Redis里面找不到这个验证码，都表示验证码不对
        String code = ( String ) RedisUtils.get ( studentEntity.getStuMobile () );
        if ( studentEntity.getCode ().equals ( code ) ) {
            StudentEntity student = new StudentEntity ();
            student.setStuMobile ( studentEntity.getStuMobile () );
            // 查询该手机号是否存在
            student = iStudentService.querySingle ( student );
            if ( student == null ) {
                studentEntity = iStudentService.saveSingle ( studentEntity );
                session.removeAttribute ( studentEntity.getStuMobile () );
            } else {
                return ResultBody.fail ( StateEnum.NOT_UNIQUE_EXCE ); // 重复
            }
        } else {
            return ResultBody.fail ( StateEnum.VERIFICATION_EXCE );
        }
        return ResultBody.success ( studentEntity );
    }

    /**
     * 学生端获取短信登录
     *
     * @param studentEntity
     * @return
     */
    @RequestMapping ( "getVerification" )
    @LogPointer ( "学生端获取手机验证码接口" )
    @ResponseBody
    public ResultBody getVerification ( StudentEntity studentEntity, HttpSession session ) {
        String msgCode = AliSMS.getMsgCode ();
        String sendMSM = AliSMS.sendMSM ( studentEntity.getStuMobile (), msgCode );
        // 以手机为key设置5分钟内的缓存验证码
        session.setAttribute ( studentEntity.getStuMobile (), msgCode );
        return ResultBody.success ( sendMSM );
    }


    /**
     * 学生使用验证码登录系统，检查Redis中验证码是否正确，检查手机号是否正确
     *
     * @param studentEntity
     * @return
     */
    @RequestMapping ( "verificationLogin" )
    @LogPointer ( "学生端验证码登录" )
    @ResponseBody
    public ResultBody verificationLogin ( StudentEntity studentEntity, HttpSession session ) {
        String sms = ( String ) session.getAttribute ( studentEntity.getStuMobile () );
        if ( sms != null && sms.equals ( studentEntity.getCode () ) ) {
            StudentEntity student = iStudentService.querySingle ( studentEntity );
            if ( student == null ) {
                // 手机号不存在
                return ResultBody.fail ( StateEnum.RESULT_NULL_EXCE ); // 结果为空
            } else {
                // 可以登录
                studentEntity.setToken ( CommonUtil.getToken () );
                session.setAttribute ( "studentEntity", student );
                return ResultBody.success ( student );
            }
        } else {
            return ResultBody.fail ( StateEnum.VERIFICATION_EXCE );
        }
    }


    /**
     * 微信扫码登录，加载请求二维码
     *
     * @return
     */
//    @RequestMapping ( "/loadWxCode" )
//    public void loadWxCode ( HttpServletResponse response, HttpSession session ) {
//        String state = UUID.randomUUID ().toString ().replace ( "-", "" );
//        session.setAttribute ( "state", state );
//        try {
//            String oauthUrl = ConstUtil.WX_OAUTH_URL.replace ( "APPID", ConstUtil.WX_AppID ).replace ( "REDIRECTURL", URLEncoder.encode ( ConstUtil.WX_REDIRECT_URL, "utf-8" ) ).replace ( "SCOPE", ConstUtil.WX_SCOPE ).replace ( "STATE", state );
//            response.sendRedirect ( oauthUrl );
//        } catch ( Exception e ) {
//            e.printStackTrace ();
//        }
//    }


    /**
     * 微信扫码登录的回调地址，检查用户是否第一次登录，如果则绑定手机号；如果不是则直接登录
     *
     * @param session
     * @return
     */
//    @RequestMapping ( "checkWxLogin" )
//    public String checkWxLogin ( @RequestParam ( "code" ) String code, @RequestParam ( "state" ) String state, Model model, HttpSession session ) {
//        StudentEntity resultStudentEntity = iStudentService.wxLogin ( code, state );
//        StudentEntity student = new StudentEntity ();
//        student.setUnionid ( resultStudentEntity.getUnionid () );
//        StudentEntity studentEntity = iStudentService.querySingle ( student );
//        // 查无此人时，注册该学生用户
//        if ( studentEntity == null ) {
//            // 将解析的微信用户信息以openId为key存入缓存，给前端验证的时间为10分钟
//            RedisUtils.set ( resultStudentEntity.getUnionid (), resultStudentEntity, 300L, TimeUnit.SECONDS );
//            model.addAttribute ( "unionid", resultStudentEntity.getUnionid () );
//            return "verify";
//        } else {
//            // 如果查到就将微信最新返回的用户信息更新为本地数据
//            resultStudentEntity.setId ( studentEntity.getId () ); // 保存查询到的旧用户Id
//            String token = CommonUtil.getToken ();
//            studentEntity.setToken ( token );
//            session.setAttribute ( "studentEntity", studentEntity );
//            resultStudentEntity.setToken ( token );
//            iStudentService.updateSingle ( resultStudentEntity );
//        }
//        return "redirect:/index";
//    }


    /**
     * 绑定手机与微信
     * 拿到前端返回的unionid与手机更新用户记录，如果手机不存在则新建
     *
     * @param : {stuMobile: this.studentEntity.stuMobile,
     *          token: this.studentEntity.verification,
     * @return
     */
    @RequestMapping ( "bindPhone" )
    @ResponseBody
    public ResultBody<StudentEntity> bindPhone ( StudentEntity studentEntity, HttpSession session ) {
        String sms = ( String ) RedisUtils.get ( studentEntity.getStuMobile () );
        // 获取扫码时解析的用户微信信息，该用户仅有微信提供的信息，需要绑定手机号和学生Id
        StudentEntity studentForRedis = ( StudentEntity ) RedisUtils.get ( studentEntity.getUnionid () );
        studentForRedis.setStuMobile ( studentEntity.getStuMobile () ); // 绑定手机号
        if ( sms != null && studentEntity.getCode ().equals ( sms ) ) {
            // 说明前端验证码存在并且手机是真实的发验证码的手机
            // 通过手机查询是否存在这个学生
            StudentEntity student = new StudentEntity ();
            student.setStuMobile ( studentEntity.getStuMobile () );
            StudentEntity studentForMobile = iStudentService.querySingle ( student );
            String token = CommonUtil.getToken ();
            studentForRedis.setToken ( token );
            if ( studentForMobile == null ) {
                // 不存在这个手机号则直接插入绑定后的记录
                String password = CommonUtil.getInviteCode ( 6 );
                studentForRedis.setPassword ( password );
                studentForRedis = iStudentService.saveSingle ( studentForRedis );
            } else {
                studentForRedis.setId ( studentForMobile.getId () );
                iStudentService.updateSingle ( studentForRedis );
            }
        } else {
            return ResultBody.fail ( StateEnum.VERIFICATION_EXCE );
        }
        session.setAttribute ( "studentEntity", studentForRedis );
        return ResultBody.success ( studentForRedis );
    }


    /**
     * 重置密码
     *
     * @param studentEntity
     * @return
     */
    @RequestMapping ( "forget" )
    @LogPointer ( "忘记密码，重置密码" )
    @ResponseBody
    public ResultBody forget ( StudentEntity studentEntity, HttpSession session ) {
        String sms = (String ) session.getAttribute ( studentEntity.getStuMobile () );
        if ( sms != null && sms.equals ( studentEntity.getCode () ) ) {
            StudentEntity s = new StudentEntity ();
            s.setStuMobile ( studentEntity.getStuMobile () );
            s = iStudentService.querySingle ( s );
            if ( s != null ) {
                s.setPassword ( studentEntity.getPassword () ); // 修改密码
                s = iStudentService.updateSingle ( s );
                return ResultBody.success ( s );
            } else {
                return ResultBody.fail ( StateEnum.REQUEST_POWER_EXCE );
            }
        } else {
            return ResultBody.fail ( StateEnum.VERIFICATION_EXCE );
        }
    }

    @RequestMapping ( "logout" )
    public String logout ( HttpSession session ) {
        session.removeAttribute ( "studentEntity" );
        return "login";
    }

}
